#include <QDate>
#include <QTableWidgetItem>
#include <QStringList>
#include "queryhistorybilldialog.h"
#include "ui_queryhistorybilldialog.h"
#include "checkuiinput.h"
#include "control/bankclient.h"
#include "control/bankexception.h"
/*
 * 还有几个按键
    pageUp pageDown home end
    然后表可以使用上下键移动标亮当
    前条目，也可以使用鼠标进行点击。
*/
const char *queryHistoryBillItemHList[] = {
    "resInx" ,
    "resTransactionDate",
    "resOwnerAccountId",
    "resOtherAccountId",
    "resSummary",
    "resTransactionCash",
    "resBalance",
};

QueryHistoryBillDialog::QueryHistoryBillDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QueryHistoryBillDialog),
    pageInx_(0)
{
    ui->setupUi(this);
    //"序号            交易日期     帐号 对方帐号
    //摘要      交易金额          余额"
    header_ << "序号" << "交易日期" << "帐号"
           << "对方帐号" << "摘要" << "交易金额" << "余额";
    //开始如下几个按钮不可用，等第一次查询出结果后才可用
    ui->queryHistoryBillPageUpButton->setEnabled(false);
    ui->queryHistoryBillPageDownButton->setEnabled(false);
    ui->queryHistoryBillHomeButton->setEnabled(false);
    ui->queryHistoryBillEndButton->setEnabled(false);
}

QueryHistoryBillDialog::~QueryHistoryBillDialog()
{
    delete ui;
}

void QueryHistoryBillDialog::on_queryHistoryBillButton_clicked()
{
    //收集相关信息查询
    /*
     * 首先是搜集开始日期和结束日期构造成服务器需要的数据
        然后是当数据返回后，将数据打印到表上。
        难点：日期控件的获取和操作，表控件的获取和操作。
        账户ID
        开始日期 YYYY-MM-DD
        结束日期 YYYY-MM-DD
        这里需要注意一个问题，就是每次查询，一定是不能一次
        将所有数据全部查询出来，在教程中的做法是一次查询一
        部分来显示。这里可以这样来做，也就是查询一个当前页，
        然后缓冲一个下一页或者多个页，如果超过一个警戒值则
        再次发送进行查询。
    */
    //获取判断起始日期
    QDate sd = ui->queryHistoryBillStartDateEdit->date();
    QDate ed = ui->queryHistoryBillEndDateEdit->date();
    if(sd > ed) {
        QMessageBox::warning(this,tr("警告"),
            tr("开始日期大于结束日期"),QMessageBox::Ok);
        return;
    }
    //注意查询等于是刷新从头开始，将一些数据还原
    pageInx_ = 0;
    QString pageInxStr;
    pageInxStr.sprintf("%d",pageInx_);
    try {
        BankClient &bc = Singleton<BankClient>::Instance();
        bc.setReqResType("QueryHistoryBillDataAccess");
        //注意这里的索引也还原
        //当然可能这个缓冲也会丢失，但是为了正确性
        bc.clear();
        bc.setRawData("startDate",sd.toString("yyyy-MM-dd").toLocal8Bit());
        bc.setRawData("endDate",ed.toString("yyyy-MM-dd").toLocal8Bit());
        //还应该有个当前页的属性，返回必要的数据
        //当前需要显示的页数
        //关于显示的条目数量，简单期间就设定为固
        //定的大小，这个控件应该可以进行滚动条的添加。
        bc.setRawData("page",pageInxStr.toLocal8Bit());
        if(!bc.execDataAccess()) {
            QMessageBox::warning(this,tr("警告"),
                tr(bc.getErrorMsg()),QMessageBox::Ok);
        } else {
            //当数据返回后，将数据打印到表上。
            QString curPageItemsNumStr = bc.getResRawData("resItemsPerCurPage");
            qint32 curPageItemsNum = curPageItemsNumStr.toInt();
            QString maxPageItemsInxStr = bc.getResRawData("resMaxPageItemsInx");
            qint32 maxPageItemsInx = maxPageItemsInxStr.toInt();
            QString itemStr;
            //直接从map里面取值，首先去除到底返回了多少条目
            //然后条目的存放采用“前缀+索引”的方式进行取回
            //在业务模型处理的地方还要保存总的条目数，已经最
            //大条目上限，用来缓存条目以及健壮性进行控制。
            ui->tableWidget->setColumnCount(header_.length());//列数
            ui->tableWidget->setRowCount(curPageItemsNum);//行数
            ui->tableWidget->setHorizontalHeaderLabels(header_);
            //设置表格编辑模式，这里设置为不可编辑
            ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
            //设置表格选择模式，这里设置为整行选择
            ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            //显示表格线
            ui->tableWidget->setShowGrid(true);
            //按照条目进行插入
            //要根据请求的页计算出当前的序号索引
            for(qint32 i = 0;i < curPageItemsNum;++i) {
                for(quint32 j = 0;j < \
                    sizeof(queryHistoryBillItemHList) / \
                    sizeof(queryHistoryBillItemHList[0]);++j) {
                    itemStr.clear();
                    itemStr.sprintf("%s%d",
                        queryHistoryBillItemHList[j],
                        (i + maxPageItemsInx - curPageItemsNum));
                    QTableWidgetItem *item = \
                            new QTableWidgetItem(bc.getResRawData(itemStr.toLocal8Bit()));
                    //设置为水平和垂直对齐
                    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    ui->tableWidget->setItem(i,j,item);
                }
            }
            ui->tableWidget->show();
            //第一次查询结果出来了，这几个按钮已经可用
            ui->queryHistoryBillPageUpButton->setEnabled(true);
            ui->queryHistoryBillPageDownButton->setEnabled(true);
            ui->queryHistoryBillHomeButton->setEnabled(true);
            ui->queryHistoryBillEndButton->setEnabled(true);
        }
    } catch(BankException &e) {
        QMessageBox::critical(this,tr("严重错误"),
                    tr(e.what()),QMessageBox::Ok);
    }
}

void QueryHistoryBillDialog::on_queryHistoryBillPageDownButton_clicked()
{
    try {
        BankClient &bc = Singleton<BankClient>::Instance();
        //相当于是增量查询
        pageInx_++;
        QString pageInxStr;
        pageInxStr.sprintf("%d",pageInx_);
        //还应该有个当前页的属性，返回必要的数据
        //当前需要显示的页数
        //关于显示的条目数量，简单期间就设定为固
        //定的大小，这个控件应该可以进行滚动条的添加。
        bc.setRawData("page",pageInxStr.toLocal8Bit());
        if(!bc.execDataAccess()) {
            //这里要注意将页数还原
            pageInx_--;
            QMessageBox::warning(this,tr("警告"),
                tr(bc.getErrorMsg()),QMessageBox::Ok);
        } else {
            //当数据返回后，将数据打印到表上。
            QString curPageItemsNumStr = bc.getResRawData("resItemsPerCurPage");
            qint32 curPageItemsNum = curPageItemsNumStr.toInt();
            QString maxPageItemsInxStr = bc.getResRawData("resMaxPageItemsInx");
            qint32 maxPageItemsInx = maxPageItemsInxStr.toInt();
            QString itemStr;
            //直接从map里面取值，首先去除到底返回了多少条目
            //然后条目的存放采用“前缀+索引”的方式进行取回
            //在业务模型处理的地方还要保存总的条目数，已经最
            //大条目上限，用来缓存条目以及健壮性进行控制。
            ui->tableWidget->setColumnCount(header_.length());//列数
            ui->tableWidget->setRowCount(curPageItemsNum);//行数
            ui->tableWidget->setHorizontalHeaderLabels(header_);
            //设置表格编辑模式，这里设置为不可编辑
            ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
            //设置表格选择模式，这里设置为整行选择
            ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            //显示表格线
            ui->tableWidget->setShowGrid(true);
            //按照条目进行插入
            //要根据请求的页计算出当前的序号索引
            for(qint32 i = 0;i < curPageItemsNum;++i) {
                for(quint32 j = 0;j < \
                    sizeof(queryHistoryBillItemHList) / \
                    sizeof(queryHistoryBillItemHList[0]);++j) {
                    itemStr.clear();
                    itemStr.sprintf("%s%d",
                        queryHistoryBillItemHList[j],
                        (i + maxPageItemsInx - curPageItemsNum));
                    QTableWidgetItem *item = \
                            new QTableWidgetItem(bc.getResRawData(itemStr.toLocal8Bit()));
                    //设置为水平和垂直对齐
                    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    ui->tableWidget->setItem(i,j,item);
                }
            }
        }
    } catch(BankException &e) {
        //这里要注意将页数还原
        pageInx_--;
        QMessageBox::critical(this,tr("严重错误"),
                    tr(e.what()),QMessageBox::Ok);
    }
}

void QueryHistoryBillDialog::on_queryHistoryBillPageUpButton_clicked()
{
    try {
        BankClient &bc = Singleton<BankClient>::Instance();
        if(pageInx_ > 0) {
            pageInx_--;
        } else {
            pageInx_ = 0;
        }
        QString pageInxStr;
        pageInxStr.sprintf("%d",pageInx_);
        //还应该有个当前页的属性，返回必要的数据
        //当前需要显示的页数
        //关于显示的条目数量，简单期间就设定为固
        //定的大小，这个控件应该可以进行滚动条的添加。
        bc.setRawData("page",pageInxStr.toLocal8Bit());
        if(!bc.execDataAccess()) {
            //这里要注意将页数还原
            pageInx_++;
            QMessageBox::warning(this,tr("警告"),
                tr(bc.getErrorMsg()),QMessageBox::Ok);
        } else {
            //当数据返回后，将数据打印到表上。
            QString curPageItemsNumStr = bc.getResRawData("resItemsPerCurPage");
            qint32 curPageItemsNum = curPageItemsNumStr.toInt();
            QString maxPageItemsInxStr = bc.getResRawData("resMaxPageItemsInx");
            qint32 maxPageItemsInx = maxPageItemsInxStr.toInt();
            QString itemStr;
            //直接从map里面取值，首先去除到底返回了多少条目
            //然后条目的存放采用“前缀+索引”的方式进行取回
            //在业务模型处理的地方还要保存总的条目数，已经最
            //大条目上限，用来缓存条目以及健壮性进行控制。
            ui->tableWidget->setColumnCount(header_.length());//列数
            ui->tableWidget->setRowCount(curPageItemsNum);//行数
            ui->tableWidget->setHorizontalHeaderLabels(header_);
            //设置表格编辑模式，这里设置为不可编辑
            ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
            //设置表格选择模式，这里设置为整行选择
            ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            //显示表格线
            ui->tableWidget->setShowGrid(true);
            //按照条目进行插入
            //要根据请求的页计算出当前的序号索引
            for(qint32 i = 0;i < curPageItemsNum;++i) {
                for(quint32 j = 0;j < \
                    sizeof(queryHistoryBillItemHList) / \
                    sizeof(queryHistoryBillItemHList[0]);++j) {
                    itemStr.clear();
                    itemStr.sprintf("%s%d",
                        queryHistoryBillItemHList[j],
                        (i + maxPageItemsInx - curPageItemsNum));
                    QTableWidgetItem *item = \
                            new QTableWidgetItem(bc.getResRawData(itemStr.toLocal8Bit()));
                    //设置为水平和垂直对齐
                    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    ui->tableWidget->setItem(i,j,item);
                }
            }
        }
    } catch(BankException &e) {
        //这里要注意将页数还原
        pageInx_++;
        QMessageBox::critical(this,tr("严重错误"),
                    tr(e.what()),QMessageBox::Ok);
    }
}

void QueryHistoryBillDialog::on_queryHistoryBillHomeButton_clicked()
{
    quint32 pageInxOld_ = pageInx_;
    try {
        BankClient &bc = Singleton<BankClient>::Instance();
        pageInx_ = 0;
        QString pageInxStr;
        pageInxStr.sprintf("%d",pageInx_);
        //还应该有个当前页的属性，返回必要的数据
        //当前需要显示的页数
        //关于显示的条目数量，简单期间就设定为固
        //定的大小，这个控件应该可以进行滚动条的添加。
        bc.setRawData("page",pageInxStr.toLocal8Bit());
        if(!bc.execDataAccess()) {
            //这里要注意将页数还原
            pageInx_ = pageInxOld_;
            QMessageBox::warning(this,tr("警告"),
                tr(bc.getErrorMsg()),QMessageBox::Ok);
        } else {
            //当数据返回后，将数据打印到表上。
            QString curPageItemsNumStr = bc.getResRawData("resItemsPerCurPage");
            qint32 curPageItemsNum = curPageItemsNumStr.toInt();
            QString maxPageItemsInxStr = bc.getResRawData("resMaxPageItemsInx");
            qint32 maxPageItemsInx = maxPageItemsInxStr.toInt();
            QString itemStr;
            //直接从map里面取值，首先去除到底返回了多少条目
            //然后条目的存放采用“前缀+索引”的方式进行取回
            //在业务模型处理的地方还要保存总的条目数，已经最
            //大条目上限，用来缓存条目以及健壮性进行控制。
            ui->tableWidget->setColumnCount(header_.length());//列数
            ui->tableWidget->setRowCount(curPageItemsNum);//行数
            ui->tableWidget->setHorizontalHeaderLabels(header_);
            //设置表格编辑模式，这里设置为不可编辑
            ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
            //设置表格选择模式，这里设置为整行选择
            ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            //显示表格线
            ui->tableWidget->setShowGrid(true);
            //按照条目进行插入
            //要根据请求的页计算出当前的序号索引
            for(qint32 i = 0;i < curPageItemsNum;++i) {
                for(quint32 j = 0;j < \
                    sizeof(queryHistoryBillItemHList) / \
                    sizeof(queryHistoryBillItemHList[0]);++j) {
                    itemStr.clear();
                    itemStr.sprintf("%s%d",
                        queryHistoryBillItemHList[j],
                        (i + maxPageItemsInx - curPageItemsNum));
                    QTableWidgetItem *item = \
                            new QTableWidgetItem(bc.getResRawData(itemStr.toLocal8Bit()));
                    //设置为水平和垂直对齐
                    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    ui->tableWidget->setItem(i,j,item);
                }
            }
        }
    } catch(BankException &e) {
        //这里要注意将页数还原
        pageInx_ = pageInxOld_;
        QMessageBox::critical(this,tr("严重错误"),
                    tr(e.what()),QMessageBox::Ok);
    }
}

void QueryHistoryBillDialog::on_queryHistoryBillEndButton_clicked()
{
    quint32 pageInxOld_ = pageInx_;
    try {
        BankClient &bc = Singleton<BankClient>::Instance();
        QString maxPageInxStr = bc.getResRawData("resMaxPageNum");
        pageInx_ = maxPageInxStr.toInt();
        QString pageInxStr;
        pageInxStr.sprintf("%d",pageInx_);
        //还应该有个当前页的属性，返回必要的数据
        //当前需要显示的页数
        //关于显示的条目数量，简单期间就设定为固
        //定的大小，这个控件应该可以进行滚动条的添加。
        bc.setRawData("page",pageInxStr.toLocal8Bit());
        if(!bc.execDataAccess()) {
            //这里要注意将页数还原
            pageInx_ = pageInxOld_;
            QMessageBox::warning(this,tr("警告"),
                tr(bc.getErrorMsg()),QMessageBox::Ok);
        } else {
            //当数据返回后，将数据打印到表上。
            QString curPageItemsNumStr = bc.getResRawData("resItemsPerCurPage");
            qint32 curPageItemsNum = curPageItemsNumStr.toInt();
            QString maxPageItemsInxStr = bc.getResRawData("resMaxPageItemsInx");
            qint32 maxPageItemsInx = maxPageItemsInxStr.toInt();
            QString itemStr;
            //直接从map里面取值，首先去除到底返回了多少条目
            //然后条目的存放采用“前缀+索引”的方式进行取回
            //在业务模型处理的地方还要保存总的条目数，已经最
            //大条目上限，用来缓存条目以及健壮性进行控制。
            ui->tableWidget->setColumnCount(header_.length());//列数
            ui->tableWidget->setRowCount(curPageItemsNum);//行数
            ui->tableWidget->setHorizontalHeaderLabels(header_);
            //设置表格编辑模式，这里设置为不可编辑
            ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
            //设置表格选择模式，这里设置为整行选择
            ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
            //显示表格线
            ui->tableWidget->setShowGrid(true);
            //按照条目进行插入
            //要根据请求的页计算出当前的序号索引
            for(qint32 i = 0;i < curPageItemsNum;++i) {
                for(quint32 j = 0;j < \
                    sizeof(queryHistoryBillItemHList) / \
                    sizeof(queryHistoryBillItemHList[0]);++j) {
                    itemStr.clear();
                    itemStr.sprintf("%s%d",
                        queryHistoryBillItemHList[j],
                        (i + maxPageItemsInx - curPageItemsNum));
                    QTableWidgetItem *item = \
                            new QTableWidgetItem(bc.getResRawData(itemStr.toLocal8Bit()));
                    //设置为水平和垂直对齐
                    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    ui->tableWidget->setItem(i,j,item);
                }
            }
        }
    } catch(BankException &e) {
        //这里要注意将页数还原
        pageInx_ = pageInxOld_;
        QMessageBox::critical(this,tr("严重错误"),
                    tr(e.what()),QMessageBox::Ok);
    }
}
